#
#	This file is part of Energy@Home.
#	Copyright (C) 2009 Danny Tsang
#	
#	This file is part of Energy@Home.
#	
#	Energy@Home is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#	
#	Energy@Home is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#	
#	You should have received a copy of the GNU General Public License
#	along with Energy@Home.  If not, see <http://www.gnu.org/licenses/>.
#

__author__ = 'Danny Tsang <danny@dannytsang.co.uk>'

import os
import Core

import cPickle as pickle

import Debug
import HistoricalData
from database import MySQL
from config.Config import ConfigManager

# Configuration Manager
CONFIG = ConfigManager()

# Instantiate Logger
LOGGER = Debug.getLogger("energyathome.datalogger.offlinehandler")

def backup(historicalData):
    '''Writes historical data to file'''
    
    global CONFIG
    global LOGGER
    
    #If true exit due to exception
    exit = False
    # Get file path from config
    location = CONFIG.getConfig("Application", "offlineFile")
    #Check if config is empty
    if len(location) == 0:
        # Use current directory
        location = os.path.join(os.getcwd(), "backup.p")
        LOGGER.warning("offlineFile is empty. Using default: '" + location + "'")
    
    try:
        # Append to file
        path = file(location, "a")

        # Ensure object has data
        if historicalData is not None:
            LOGGER.info("Writing data to file:" + historicalData.__dict__)
            pickle.dump(historicalData, path)
    except IOError:
        #Debug.writeOut("Unable to write to backup file: '" + location + "'")
        # No point running program if it's unable to write to file
        exit = True
    finally:
        # Close file
        try:
            path.close()
        except UnboundLocalError:
            # File was not opened
            pass
    # Check to exit
    if exit:
        Core.shutdown()

def restore():
    '''Starts the restore process from a file.'''
    
    global LOGGER
    
    backup = restoreFromFile()
    recordCount = len(backup)
    
    if(recordCount > 0):
        LOGGER.info(str(recordCount) + "record(s) found. Saving to DB")
        for record in backup:
            LOGGER.info("Inserting: " + record.__dict__)
            HistoricalData.insertData(record)
        # Remove backup file to prevent duplicate data from being restored.
        LOGGER.info("Restore from backup complete.")
        LOGGER.info("Removing backup file.")
        LOGGER.info("File deleted? " + str(deleteBackupFile()))

def restoreFromFile():
    '''Reads a file and returns an array of objects.'''
    
    global CONFIG
    global LOGGER
    
    # List to store restored objects
    list = []
    # Get file path from config
    location = CONFIG.getConfig("Application", "offlineFile")
    #Check if config is empty
    if len(location) == 0:
        # Use current directory
        location = os.path.join(os.getcwd(), "backup.p")
        LOGGER.info("offlineFile is empty. Using default: '" + location + "'")
    # Check file exists before deleting
    if os.path.exists(location):
        # Create file object
        path = file(location, "r")
        # Read file till end of file
        try:
            while True:
                list.append(pickle.load(path))
        except EOFError:
            # Ignore end of file error
            pass
        finally:
            # Close file
            path.close()
            
    LOGGER.info("Found " + str(len(list)) + " record(s) in '" + location + "'")
    return list

def deleteBackupFile():
    '''Removed backup file if it exists.'''
    
    global CONFIG
    global LOGGER
    
    success = False;
    
    # Get file path from config
    location = CONFIG.getConfig("Application", "offlineFile")
    #Check if config is empty
    if len(location) == 0:
        # Use current directory
        location = os.path.join(os.getcwd(), "backup.p")
        LOGGER.info("offlineFile is empty. Using default: '" + location + "'")
    # Check file exists before deleting
    if os.path.exists(location):
        # Delete file
        try:
            os.remove(location)
            success = True;
        except OSError:
            LOGGER.error("Unable to remove file: '" + location + "'")
    
    return success;